package cinvestav.adviseme.webservice;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import cinvestav.adviseme.controller.FotoController;
import cinvestav.adviseme.datamodel.Foto;
import cinvestav.adviseme.util.DBException;
import cinvestav.adviseme.util.DataBaseDictionary;
import cinvestav.adviseme.util.QueryParamDictionary;

@Path("/fotos")
public class FotoWebService {
	private static Logger log = Logger.getLogger(FotoWebService.class.getName());
	protected FotoController fotoController;
	
	public FotoWebService() throws DBException{
		fotoController = new FotoController();
	}
	
	@GET
	@Produces({MediaType.APPLICATION_JSON})
	@Path("/getFotos")
	public List<Foto> getsPhotos(@QueryParam(QueryParamDictionary.LUGAR_ID) String id_lugar){
		Map<String,String[]> mapConsulta = new HashMap<String,String[]>();
		String parametros[] = new String[2];
		
		parametros[0] = id_lugar;
		parametros[1] = DataBaseDictionary.COLUMN_TYPE_COMENTARIO_ID_LUGAR;
		mapConsulta.put(DataBaseDictionary.COLUMN_FILTRO_NAME_COMENTARIO_ID_LUGAR, parametros);
		try {
			List<Foto> fotos = new LinkedList<Foto>();
			fotos = fotoController.getByFilters(mapConsulta);
			if (fotos.isEmpty()){
				fotos.add(new Foto());
			}
			log.log(Level.INFO,"FOTOS = "+fotos); 
			return fotos;			
		} catch (DBException e) {
			// TODO: handle exception
			log.log(Level.SEVERE,null,e);
			throw new WSErrorException(e.getMessage());
		}
		
	}
	
	@POST
	@Produces({ MediaType.APPLICATION_JSON })
	@Consumes({ MediaType.APPLICATION_JSON })
	@Path("/subirFoto")
	public Foto getEnviarFoto(JSONObject requestFotoJSON) {
		// Los parametros se obtienen como un objeto JSON y es necesario
		// realizar el parseo

		// Objeto que almacenara la foto en formato JSON
		JSONObject fotoJSON;
		// Objeto que almacenara la persona en formato JSON
		JSONObject personaJSON;
		// Objeto que almacenara el lugar en formato JSON
		JSONObject lugarJSON;
		// Lista de resultados
		
		//Fotografia que sera almacenada
		Foto foto= new Foto();

		try {
			log.log(Level.INFO, "request = " + requestFotoJSON.toString());
			// Se obtiene el objeto JSON del REQUEST, mediante el nombre
			// de parametro ingresado
			fotoJSON = new JSONObject(
					requestFotoJSON
							.getString(QueryParamDictionary.FOTO_PARAM));
			personaJSON = fotoJSON.getJSONObject("persona");
			lugarJSON = fotoJSON.getJSONObject("lugar");

			log.log(Level.INFO, "Foto = " + fotoJSON.toString());
			log.log(Level.INFO, "Persona = " + personaJSON.toString());
			log.log(Level.INFO, "Lugar = " + lugarJSON.toString());

			foto.getLugar().setId(lugarJSON.getInt("id"));
			foto.getPersona().setId(personaJSON.getInt("id"));
			foto.setUrl(fotoJSON.getString("url"));
		
			log.log(Level.INFO, "Foto= " + foto);
		} catch (JSONException e) {
			// Si ocurre un error al parsear los parametros se retorna este
			// error al cliente
			log.log(Level.SEVERE, null, e);
			throw new WSErrorException("PARAMETROS INCORRECTOS");
		}

		try {
			return fotoController.insert(foto);
		} catch (DBException e) {
			// TODO Auto-generated catch block
			log.log(Level.SEVERE, null, e);
			throw new WSErrorException(e.getMessage());
		}
	}
	
	@POST
	@Path("/upload")
	@Produces("text/plain")
	public String loadFile(@Context HttpServletRequest request) {
		String resultStatus = "fail";
		if (ServletFileUpload.isMultipartContent(request)) {
			FileItemFactory factory = new DiskFileItemFactory();
			ServletFileUpload upload = new ServletFileUpload(factory);
			List<FileItem> items = null;
			try {
				items = upload.parseRequest(request);
			} catch (FileUploadException e) {
				e.printStackTrace();
			}
			if (items != null) {
				ServletContext context = request.getSession().getServletContext();
				Iterator<FileItem> iter = items.iterator();
				while (iter.hasNext()) {
					FileItem item = iter.next();
					if (!item.isFormField() && item.getSize() > 0) {
						String fileName = processFileName(item.getName());
						try {

							File x = new File(context.getRealPath("/pics")+"/" + fileName);
							String path=x.getAbsolutePath();
							item.write(x);
							return "/pics/"+fileName;
						} catch (Exception e) {
							e.printStackTrace();
						}
						resultStatus = "ok";
					}
				}
			}
		}
		return resultStatus;
	}

	private String processFileName(String fileNameInput) {
		String fileNameOutput = null;
		Integer dotIndex = fileNameInput.lastIndexOf(".");
		fileNameOutput = fileNameInput.substring(
				fileNameInput.lastIndexOf("\\") + 1, dotIndex);
		Random rand = new Random();
		rand.setSeed(System.currentTimeMillis());
		fileNameOutput += ""+rand.nextInt(1000000);
		fileNameOutput += fileNameInput.substring(dotIndex);
		return fileNameOutput;
	}
	
}
